import io
import os
from datetime import datetime

from apps import app_vedio_playbook
from base import oss_client
from service import service_imgs, service_video_chatveo, service_playbook
from utils import utils
from model.models import db, TSysNovelChapter, TSysVideo, TSysFile, TSysTokenUsageHistory
from configs import configs_service



def create_video(chapter_id, task_id, video_id):
    create_error_code = None
    try:
        save_video_create_task_start_time(video_id=video_id, task_start_time=datetime.now())
        novelChapter = TSysNovelChapter.query.filter_by(id=chapter_id).first()
        if novelChapter is None:
           print("小说章节为空")
           app_vedio_playbook.change_video_create_status(video_id=video_id, status=app_vedio_playbook.CREATE_STATUS_ERROR, create_error_code='E0001')
           return

        user_id = novelChapter.user_id
        novel_id = novelChapter.novel_id
        character_appearances = service_playbook.get_character_appearance(novel_id=novel_id)
        if character_appearances.get("success") == False:
            #没有有人物外貌,则先创建人物外貌
            if character_appearances.get("value") is None:
                extrac_success = service_playbook.character_appearance_extraction(novel_id=novel_id)
                if extrac_success.get("success") == False:
                    print("人物外貌创建异常! 原因为:" + str(extrac_success.get("msg")))
                    app_vedio_playbook.change_video_create_status(video_id=video_id, status=app_vedio_playbook.CREATE_STATUS_ERROR, create_error_code='E0002')
                    return

        record_video_create_progress(video_id=video_id, percent=10)
        character_appearances = service_playbook.get_character_appearance(novel_id=novel_id)
        playbooks = service_playbook.create_playbook_by_chapter_v2(chapter_id=chapter_id, character_appearances=character_appearances.get("value"))
        if playbooks.get("success") == False:
            print("视频脚本创建异常，原因为：" + str(playbooks.get("msg")))
            app_vedio_playbook.change_video_create_status(video_id=video_id, status=app_vedio_playbook.CREATE_STATUS_ERROR, create_error_code='E0003')
            return

        record_video_create_progress(video_id=video_id,percent=20)

        create_video_result = service_video_chatveo.create_video_from_chatveo(playboosks_json=playbooks, chapter_id=chapter_id, user_id=user_id)
        record_video_create_progress(video_id=video_id, percent=80)

        if create_video_result is not None and create_video_result.get("success") == True:
            save_video_cover_img(video_id=video_id,cover_img_name=create_video_result.get('value').get('cover_image_file_name'))
            record_video_create_progress(video_id=video_id,percent=100)
            video_file_path = create_video_result.get("value").get("video_file_path")
            video_duration = service_video_chatveo.get_video_duration(file_path=video_file_path)
            save_video_create_token_usage(call_chatveo_endpoint_conut=create_video_result.get("value").get("call_chatveo_endpoint_conut"), user_id=user_id, video_id=video_id)

            try:
                after_create_vedio_success(video_id=video_id, video_duration=video_duration,  video_msg=create_video_result.get("value"))
            except Exception as e:
                print('创建视频成功后清理任务异常：' + str(e))
        else:
            print("创建视频异常! ")
            app_vedio_playbook.change_video_create_status(video_id=video_id, status=app_vedio_playbook.CREATE_STATUS_ERROR, create_error_code='E0007')
            return
    except Exception as e:
        app_vedio_playbook.change_video_create_status(video_id=video_id, status=app_vedio_playbook.CREATE_STATUS_ERROR, create_error_code='E0000')
        print(e)

##辅助函数-------------------------------------------------------------##
def save_video_create_task_start_time(video_id,task_start_time):
    if video_id is None:
        return False
    video = TSysVideo.query.get(video_id)
    if video is None:
        return False
    video.create_task_start_time = task_start_time
    db.session.commit()
    return True


def record_video_create_progress(video_id, percent):
    if video_id is None or percent is None:
        return False
    video = TSysVideo.query.get(video_id)
    if video is None:
        return False
    video.create_progress = percent
    if percent == 100:
        video.create_stauts = 2
    elif percent > 0 and percent < 100:
        video.create_stauts = 1
    db.session.commit()
    return True

def save_video_cover_img(video_id, cover_img_name):
    if video_id is None or cover_img_name is None:
        return False
    try:
        video = TSysVideo.query.get(video_id)
        if video is None:
            return False
        video.cover_img_name = cover_img_name
        video.cover_img_base64 = get_cover_image_base64(user_id=video.user_id, cover_img_name=cover_img_name)
        db.session.commit()
        return True
    except Exception as e:
        # todo:log
        print(e)
        return False


def get_cover_image_base64(user_id,cover_img_name):
    tsysfile = TSysFile.query.filter_by(user_id=user_id, local_path=cover_img_name).first()
    if tsysfile is None:
        #todo:log
        return ""

    file_iter = oss_client.get_object(tsysfile.remote_path, tsysfile.local_path)
    file_data = io.BytesIO()
    for data in file_iter:
        file_data.write(data)
    file_data.seek(0)

    file_data = service_imgs.resize_image(file_data, desired_size=(128, 128))

    return utils.image_to_base64(image=file_data,content_type='image/png')


def after_create_vedio_success(video_id, video_duration, video_msg):
    if video_msg is None:
        return False

    audio_temp_path = video_msg.get("audio_temp_path")
    mixed_audio_path = video_msg.get("mixed_audio_path")
    video_file_path = video_msg.get("video_file_path")
    imgs_path = video_msg.get("imgs_path")
    video_name = video_msg.get("oss_video_file_name")
    videos_temp_chpater_path = video_msg.get("videos_temp_chpater_path")

    #将video表中的字段补全
    if video_id is None:
        return False
    video = TSysVideo.query.get(video_id)
    if video is None:
        return False

    video.file_id = video_msg.get("file_id")
    video.file_name = video_msg.get("file_name")
    video.video_type = service_video_chatveo.type_MP4
    video.create_success_time = datetime.now()
    video.video_duration = video_duration
    video.file_name = video_name
    db.session.commit()

    #删除临时文件
    #创建成功以后的善后工作
    if imgs_path is not None:
        for file in os.listdir(imgs_path):
            os.remove(imgs_path + os.sep + file)
        os.removedirs(imgs_path)
    if audio_temp_path is not None:
        for file in os.listdir(audio_temp_path):
            os.remove(audio_temp_path + os.sep + file)
        os.removedirs(audio_temp_path)
    if mixed_audio_path is not None:
        os.remove(path=mixed_audio_path)
    if video_file_path is not None:
        os.remove(path=video_file_path)
    if videos_temp_chpater_path is not None:
        for file in os.listdir(videos_temp_chpater_path):
            os.remove(videos_temp_chpater_path + os.sep + file)
        os.removedirs(videos_temp_chpater_path)
    return True


def save_video_create_token_usage(call_chatveo_endpoint_conut,user_id,video_id):
    video_token_price_v2 = configs_service.get_config('video_token_price_v2')
    if video_token_price_v2 is None:
        video_token_price_v2 = 5000
    total_token_usage = call_chatveo_endpoint_conut * video_token_price_v2
    tokenUsageHistory = TSysTokenUsageHistory(
        user_id=user_id,
        input_tokens=0,
        output_tokens=total_token_usage,
        total_tokens=total_token_usage,
        create_date=datetime.now(),
        updated_date=datetime.now(),
    )
    db.session.add(tokenUsageHistory)
    db.session.commit()
    video = TSysVideo.query.filter_by(id=video_id).first()
    if video is not None:
        video.has_checked_token=1
        db.session.commit()
